
/*****
 * 输出帮助
 */
function outputHelp() {
    console.log("<命令> <m3u8URL> <路径> <文件名>");
    console.log("或者");
    console.log("<命令> <m3u8文件路径> <url前缀> <文件名>");
}


/*********
 * 下载并解析m3u8
 * @m3u8URL m3u8地址
 * @callback 回调函数，参数有 tsArray 解析后的视频片段地址数组
 */
function downloadM3u8File(m3u8URL, m3u8FileName, callback) {
    let cp = require('child_process');
    let fs = require('fs');
    let rl = require('readline');


    if (m3u8URL) {
        cp.exec("wget -O " + m3u8FileName + " " + m3u8URL, function () {
            var tsArray = [];
            var rlo = rl.createInterface({
                input: fs.createReadStream(m3u8FileName)
            });

            rlo.on('line', (line) => {
                if (line && line.indexOf("#") != 0) {
                    tsArray.push(line);
                }
            });

            rlo.on('close', function () {
                if (callback) {
                    callback(tsArray);
                }

            })
        })
    } else {
        var tsArray = [];
        var rlo = rl.createInterface({
            input: fs.createReadStream(m3u8FileName)
        });

        rlo.on('line', (line) => {
            if (line && line.indexOf("#") != 0) {
                tsArray.push(line);
            }
        });

        rlo.on('close', function () {
            if (callback) {
                callback(tsArray);
            }

        })
    }

}


function renameVideoClip(tsArray, dir, callback) {
    let cp = require('child_process');
    var mvFun = function (index) {
        if (index == 0) {
            if (callback) {
                callback();
            }
        } else {
            var nextIndex = index - 1;
            var ts = tsArray[nextIndex];
            var oldName = ts.substring(ts.lastIndexOf("/") + 1);
            var newName = oldName.substring(0, oldName.indexOf("?"));
            oldName = oldName.replace(/&/g, "\\&");
            oldName = oldName.replace("?", "\\?");
            var cmd = "mv " + dir + oldName + " " + dir + newName;
            console.log(cmd);
            cp.exec(cmd, mvFun(nextIndex));
        }
    };
    mvFun(tsArray.length);
}

/***********
 * 下载视频片段
 * @tsArray 解析的视频地址数组
 * @dir 下载路径
 * @urlPrefix URL前缀
 * @callback 回调函数
 */
function downVideoClip(tsArray, dir, urlPrefix, callback) {
    let cp = require('child_process');
    let fs = require('fs');

    var dlStr = urlPrefix + tsArray[0];
    for (var i = 1; i < tsArray.length; i++) {
        var ts = tsArray[i]
        dlStr += "\n";
        dlStr += urlPrefix;
        dlStr += ts;
    }

    var dlFileName = dir + "v.dl";
    fs.writeFile(dlFileName, dlStr, function (err) {
        cp.exec("wget -P " + dir + " -i " + dlFileName, function () {
            var mvFun = function (index) {
                if (index == 0) {
                    if (callback) {
                        callback();
                    }
                } else {
                    var nextIndex = index - 1;
                    var ts = tsArray[nextIndex];
                    var oldName = ts.substring(ts.lastIndexOf("/") + 1);
                    var newName = oldName.substring(0, oldName.indexOf("?"));
                    oldName = oldName.replace(/&/g, "\\&");
                    oldName = oldName.replace("?", "\\?");
                    var cmd = "mv " + dir + oldName + " " + dir + newName;
                    console.log(cmd);
                    cp.exec(cmd, mvFun(nextIndex));
                }
            };
            mvFun(tsArray.length);
        });
    });
}


/**********
 * 合并视频
 * @tsArray 解析的视频地址数组
 * @dir 下载路径
 * @mp4File 合并后文件名称
 * @callback 回调函数
 */
function mergeVideo(tsArray, dir, mp4File, callback) {
    let cp = require('child_process');
    let fs = require('fs');

    var cliFileName = dir + "v.cli";

    var ts = tsArray[0];
    var tsName = ts.substring(ts.lastIndexOf("/") + 1);
    tsName = tsName.substring(0, tsName.indexOf("?"))

    var cliStr = "ffmpeg -i \"concat:" + tsName;
    for (var i = 1; i < tsArray.length; i++) {
        var ts = tsArray[i];
        cliStr += "|";
        var tsName = ts.substring(ts.lastIndexOf("/") + 1);
        tsName = tsName.substring(0, tsName.indexOf("?"))
        console.log(tsName);
        cliStr += tsName;
    }

    cliStr += "\" -acodec copy -vcodec copy -absf aac_adtstoasc " + mp4File;
    fs.writeFile(cliFileName, cliStr, function () {
        cp.exec("chmod 755 " + cliFileName, function () {

            cp.exec(cliFileName, { cwd: dir }, function (err) {
                if (err) {
                    console.log(err);
                    return;
                }
                if (callback) {
                    callback();
                }
            })
        });
    });
}


/**********
 * 下载视频
 */
function downloadVideo() {

    var m3u8URL = process.argv[2]; //https://jdvodrvfb210d.vod.126.net/jdvodrvfb210d/nos/hls/2018/09/19/1010533600_4484e719becc4447bfb3bfc186a83a5a_sd.m3u8
    var mp4File = process.argv[4];

    var dir;
    var m3u8FileName;
    var urlPrefix;

    if (m3u8URL.indexOf("http") == 0) {
        dir = process.argv[3];
        m3u8FileName = dir + "v.m3u8";
        urlPrefix = m3u8URL.substring(0, m3u8URL.lastIndexOf('/') + 1);
    } else {
        m3u8FileName = m3u8URL;
        dir = m3u8FileName.substring(0, m3u8FileName.lastIndexOf('/') + 1);
        urlPrefix = process.argv[3];
        m3u8URL = null;
    }



    console.log("开始下载。。。");

    downloadM3u8File(m3u8URL, m3u8FileName, function (tsArray) {

        downVideoClip(tsArray, dir, urlPrefix, function () {

            mergeVideo(tsArray, dir, mp4File, function () {
                console.log("下载完成！");
            });

        });

    });


}


//执行主要方法
if (process.argv[2] == "help" || process.argv.length < 5) {
    outputHelp();
} else {
    downloadVideo();
}


// 测试重命名
// downloadM3u8File(null, "/home/luwenhe/视频/网课/2020-04-14/古对今/v.m3u8", function (tsArray) {
//     renameVideoClip(tsArray, "/home/luwenhe/视频/网课/2020-04-14/古对今/");
// });